using System.Collections.Generic;
using UnityEngine;
using System.Linq;

namespace FrameWork
{
    public class ObjectPool : SingletonMono<ObjectPool>
    {
        // 预制体路径
        private const string PREFAB_PATH = "Prefabs/"; // 确保预制体位于 Assets/Resources/Prefabs 文件夹中

        // 用于存放所有的对象池，根据名字进行区分
        private Dictionary<string, Stack<GameObject>> objectPoolDic = new Dictionary<string, Stack<GameObject>>();

        /// <summary>
        /// 创建物体
        /// </summary>
        /// <param name="name">预制体的名称</param>
        /// <returns>实例化的物体</returns>
        public GameObject Spawn(string name)
        {
            GameObject obj = null;

            // 判断对象池中是否有可用对象
            if (objectPoolDic.ContainsKey(name) && objectPoolDic[name].Count > 0)
            {
                // 从对象池中取出对象并激活
                obj = objectPoolDic[name].Pop();
                obj.SetActive(true);
                // Debug.Log("从对象池中获取对象: " + name);
            }
            else
            {
                // 加载预制体
                string prefabPath = PREFAB_PATH + name;
                GameObject prefab = Resources.Load<GameObject>(prefabPath);

                if (prefab != null)
                {
                    // 实例化对象
                    obj = Instantiate(prefab);
                    obj.name = name;
                    // Debug.Log("从 Resources 加载并实例化对象: " + name);
                }
                else
                {
                    Debug.LogError("资源加载失败: " + prefabPath);
                }
            }

            return obj;
        }

        /// <summary>
        /// 将物体添加到对象池
        /// </summary>
        /// <param name="name">物体名称/路径</param>
        /// <param name="gameObject">需要添加的物体</param>
        public void Replace(string name, GameObject gameObject)
        {
            if (gameObject == null)
            {
                Debug.LogError("尝试添加空物体到对象池！");
                return;
            }

            gameObject.SetActive(false);

            if (!objectPoolDic.ContainsKey(name))
            {
                objectPoolDic.Add(name, new Stack<GameObject>());
            }

            objectPoolDic[name].Push(gameObject);
        }

        /// <summary>
        /// 清除对应对象池
        /// </summary>
        /// <param name="prefabName">物体名称</param>
        public void Clear(string prefabName)
        {
            if (objectPoolDic.TryGetValue(prefabName, out Stack<GameObject> stack))
            {
                // 循环销毁对象池中的所有对象
                while (stack.Count > 0)
                {
                    GameObject obj = stack.Pop();
                    if (obj != null)
                    {
                        GameObject.Destroy(obj.gameObject);
                    }
                }

                objectPoolDic.Remove(prefabName);
            }
        }

        /// <summary>
        /// 清空所有对象池
        /// </summary>
        public void ClearAll()
        {
            // 提取所有对象到列表中
            var allObjects = objectPoolDic.Values.SelectMany(stack => stack).ToList();
            
            // 销毁所有对象
            foreach (var obj in allObjects)
            {
                if (obj != null)
                {
                    GameObject.Destroy(obj.gameObject);
                }
            }
            
            // 清空字典
            objectPoolDic.Clear();
        }
    }
}